package android.mcsmtms.fragment;

import java.math.BigDecimal;
import java.math.RoundingMode;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.mcsmtms.R;
import android.mcsmtms.activity.LoginActivity;
import android.mcsmtms.activity.McsmtmsActivity;
import android.mcsmtms.activity.SendReportActivity;
import android.mcsmtms.constant.GlobalConstants.GPSConstants;
import android.mcsmtms.manager.GPSCallback;
import android.mcsmtms.manager.GPSManager;
import android.mcsmtms.manager.SpeedManager;
import android.mcsmtms.settings.AppSettings;
import android.mcsmtms.util.Utilities;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.AbsoluteSizeSpan;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MonitorSpeedFragment extends Fragment implements GPSCallback {
	private static View view;
	private GPSManager gpsManager = null;
	private static Handler enableGpsHandler;
	private TextView speedTextView;
	private AbsoluteSizeSpan sizeSpanLarge = null;
	private AbsoluteSizeSpan sizeSpanSmall = null;
	private SpeedManager speedManager;
	private double speed = 0.0;
	public static LatLng marikinaLatLng = new LatLng(14.650399, 121.102417);
	private GoogleMap map;
	private Location currentLocation;
	private boolean isGpsAlertDialogActive = false;
	private AlertDialog promptDialog;
	private double minSpeedPercentage = 0.15;
	private CountDownTimer countDownTimer; 

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// return container;
		// Inflate the layout for this fragment
		// return inflater.inflate(R.layout.fragment_monitor_speed, container,
		// false);

		if (view != null) {
			ViewGroup parent = (ViewGroup) view.getParent();
			if (parent != null)
				parent.removeView(view);
		}
		try {
			view = inflater.inflate(R.layout.fragment_monitor_speed, container,
					false);
		} catch (InflateException e) {
			/* map is already there, just return view as it is */
		}
		return view;
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onActivityCreated(savedInstanceState);

		if (savedInstanceState != null) {
			return;
		}
		// init map
		FragmentManager fragmentManager = getFragmentManager();
		Fragment mapFragment = fragmentManager
				.findFragmentById(R.id.map_report);
		map = ((SupportMapFragment) mapFragment).getMap();

		map.animateCamera(CameraUpdateFactory.newLatLngZoom(marikinaLatLng, 14));

		// init gpsManager
		gpsManager = new GPSManager();
		gpsManager.startListening(getActivity().getApplicationContext());
		gpsManager.setGPSCallback(this);

		enableGpsHandler = new Handler() {
			public void handleMessage(Message msg) {
				isGpsAlertDialogActive = false;
				Intent intent = new Intent(
						Settings.ACTION_LOCATION_SOURCE_SETTINGS);
				getActivity().startActivity(intent);
			}
		};

		// check if GPS is enabled
		// else raise message and redirect use to gps settings
		checkGps();

		// init speed-related text views
		speedTextView = (TextView) getActivity().findViewById(
				R.id.tv_value_speed);

		setSpeedText(0.00);
		speedManager = new SpeedManager();
		map.setMyLocationEnabled(true);
		
		// init send report button
		getActivity().findViewById(R.id.btn_send_report).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						//attemptLogin();
						
						Intent goToSendReportIntent = new Intent(getActivity(), SendReportActivity.class);
						goToSendReportIntent.putExtra("currentLocation", map.getMyLocation());
						getActivity().startActivity(goToSendReportIntent);
					}
				});
	}
	
	@Override
	public void onCreateOptionsMenu(Menu menu, android.view.MenuInflater inflater) {
		//inflater.inf
		super.onCreateOptionsMenu(menu, inflater);
	};
	
	@Override
	public void onGPSUpdate(Location location) {
		String title = "Speed Slow Down";
		String message = "Send Report";

		speedManager.addLocation(location);

		// ((TextView) findViewById(R.id.label_lat_value)).setText(String
		// .valueOf(roundDecimal(location.getLatitude(), 2)));
		// ((TextView) findViewById(R.id.label_long_value)).setText(String
		// .valueOf(roundDecimal(location.getLongitude(), 2)));

		if (location.hasSpeed())
			speed = roundDecimal(convertSpeed(location.getSpeed()), 2);
		else
			speed = roundDecimal(
					convertSpeed(speedManager.computeCurrentSpeed()), 2);

		// averageSpeed = roundDecimal(speedManager.getAverageSpeed(), 2);

		setSpeedText(speed);
		currentLocation = location;
		double averageSpeed = convertSpeed(speedManager.getAverageSpeed());
		
		Toast.makeText(getActivity(), "average speed: " + averageSpeed + " listSize: " + speedManager.getLocationListSize() + " sumSpeed:" + speedManager.getSumSpeed(), Toast.LENGTH_SHORT).show();
		if (speed < (averageSpeed * minSpeedPercentage)
				&& promptDialog == null) {

			promptDialog = Utilities.showDefaultAlertDialog(getActivity(),
					promptOkOnClickListener, promptCancelOnClickListener,
					title, message);
			startCountDownForDialog();
		}
		
		//Toast.makeText(getActivity(), "onGpsUpdate: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
		//drawMarker(location);
	}

	// @Override
	@Override
	public void onResume() {
		super.onResume();
		if(!isGpsAlertDialogActive)
			checkGps();
	}

	private boolean isGpsEnabled() {
		// String provider = Settings.Secure.getString(getActivity()
		// .getContentResolver(),
		// Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
		boolean isGpsEnabled = gpsManager
				.isProviderEnabled(LocationManager.GPS_PROVIDER);
		return isGpsEnabled;
	}

	private void checkGps() {
		if (isGpsEnabled()) {
			// Location providers enabled
			Toast.makeText(getActivity(), "GPS Enabled!", Toast.LENGTH_LONG)
					.show();
		} else {
			isGpsAlertDialogActive = true;
			Utilities.showDefaultAlertDialog(getActivity(), "Enable GPS",
					"Enable GPS", enableGpsHandler);
		}
	}

	private void drawMarker(Location location) {
		map.clear();
		LatLng currentPosition = new LatLng(location.getLatitude(),
		location.getLongitude());
		map.addMarker(new MarkerOptions()
			.position(currentPosition)
			.snippet("Lat:" + location.getLatitude() + "Lng:"+ location.getLongitude()).
			icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
			    .title("ME"));
		
		map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 14));
	}

	private void setSpeedText(double value) {
		String speedText = String.valueOf(value) + " "
				+ AppSettings.getMeasureUnitString(getActivity());
		Spannable span = new SpannableString(speedText);
		int firstPos = speedText.indexOf(32);

		span.setSpan(sizeSpanLarge, 0, firstPos,
				Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		span.setSpan(sizeSpanSmall, firstPos + 1, speedText.length(),
				Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

		speedTextView.setText(span);
	}

	private double convertSpeed(double speed) {
		return ((speed * GPSConstants.HOUR_MULTIPLIER) * GPSConstants.UNIT_MULTIPLIERS[AppSettings
				.getMeasureUnit(getActivity())]);
	}

	private double roundDecimal(double value, final int decimalPlace) {
		double retValue = 0;
		try {
			BigDecimal bd = new BigDecimal(value);

			bd = bd.setScale(decimalPlace, RoundingMode.HALF_UP);
			retValue = bd.doubleValue();
		} catch (Exception ex) {
			ex.printStackTrace();
			// Log.e(MonitorSpeed.class.getName(), ex.getMessage());
		}

		return retValue;
	}

	@Override
	public void onDestroyView() {
		try {
			if (gpsManager != null) {
				gpsManager.stopListening();
				gpsManager.setGPSCallback(null);
				gpsManager = null;
			}
		} catch (Exception ex) {
			// TODO: Replace with appropriate error dialog.
			Toast.makeText(
					getActivity(),
					"Error in stopping GPS Manager: "
							+ ex.getLocalizedMessage(), Toast.LENGTH_LONG)
					.show();
		}
		super.onDestroyView();
	}
	
	private DialogInterface.OnClickListener promptOkOnClickListener = new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int arg1) {
			dialog.dismiss();
			promptDialog = null;
			if(countDownTimer != null) {
				countDownTimer.cancel();
			}
				
			Intent sendReportIntent = new Intent(getActivity(), SendReportActivity.class);
			getActivity().startActivity(sendReportIntent);
		}
	};

	private DialogInterface.OnClickListener promptCancelOnClickListener = new DialogInterface.OnClickListener() {
		@Override
		public void onClick(DialogInterface dialog, int arg1) {
			if(countDownTimer != null) {
				countDownTimer.cancel();
			}
			dialog.dismiss();
			promptDialog = null;
		}
	};
	
	private void startCountDownForDialog() {
		countDownTimer = new CountDownTimer(5000, 1000) {
			@Override
			public void onTick(long arg0) { /* do nothing */
			}

			@Override
			public void onFinish() {
				if(promptDialog != null) {
					promptDialog.dismiss();
					promptDialog = null;
				}
			}
		};
		countDownTimer.start();
	}

}
